import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
import cx from 'classnames';
import WPT from 'wpt';

import styles from './styles.m.less';

import apiClient, { WPT_API_TYPE } from '@wpt/apiClient';

// 消息类型
const NOTIFICATION = 'notification'; // 提醒类型
const PUSH = 'push'; // 推送类型

const CALL_CENTER_ROUTE = '/webApp/im/callCenter';

const SESSION_KEY = 'querying_notification';

const API = WPT.Util.handleApi(
    { realNews: '/v1.0/notice/real-news' },
    {
        hostname: WPT.apiConfig.IM,
        namespace: 'msg',
        useEnv: true,
    }
);

@apiClient(
    {
        notification: 'user/noReadMsg', // 查看新消息通知
        dismiss: 'user/kickNoRead', // 移除提醒
    },
    WPT_API_TYPE
)
export default class MessageAlert extends PureComponent {
    container = {
        top: 0,
        bottom: 0,
    };

    pushContainer = {
        top: 0,
        bottom: 0,
    };

    firstQuery = true;

    constructor(props, API) {
        super(props);

        this.API = API;
        this.state = {
            currentRoute: window.location.pathname,
            received: false,
            messageUrl: '',
            count: 0,
            type: NOTIFICATION,
        };

        this.pageChangeListener();

        // 进入过消息中心后，进行高速轮询
        // 进入消息中心后，在 session 中进行记录
        if (WPT.curRouter === CALL_CENTER_ROUTE || window.sessionStorage.getItem(SESSION_KEY)) {
            this.startMessageQueryingRapidly();
        } else {
            // 否则慢速轮询
            this.startMessageQueryingSlowly();
        }
    }

    isInBlackList = () => {
        const { currentRoute: route } = this.state;

        return (
            !!route &&
            (route.startsWith('/my/order') || // 订单
                route.startsWith('/my/sale')) // 订单
        );
    };

    isInWhiteList = () => {
        const { currentRoute: route } = this.state;

        return (
            !!route &&
            (route === '/' ||
            route.startsWith('/home') || // 首页
            route.startsWith('/webApp/discovery') || // 逛逛页面
            route.startsWith('/handpickGoods') || // 精选好物
            route.startsWith('/live/channel') || // 直播列表页
            route.startsWith('/attention') || // 关注页面
            route.startsWith('/recommend') || // 精选页面
            route.startsWith('/uri') || // 拍品详情页
            route.startsWith('/category') || // 分类页面
            route.startsWith('/find') || // 发现页
            route.startsWith('/featured') || // 发现页 -> 精选
            route.startsWith('/goodShop') || // 优店
            route.startsWith('/raise/newDaily') || // 天天抽奖
            route.startsWith('/cheap') || // 捡漏
            route.startsWith('/webApp/shopMessage') || // 新品开拍
            route.startsWith('/my') || // 个人中心
            route.startsWith('/shop') || // 店铺中心
            route.startsWith('/college/expert') || // 专家说
            route.startsWith('/webApp/article/detail') || // 文章详情
                route.startsWith('/webApp/standardGoods/saleList')) // 一口价
        );
    };

    isRouteAvaliable = () => this.isInWhiteList() && !this.isInBlackList();

    // x秒后清空消息提示
    setAutoReset = () => {
        const TIMEOUT = 5 * 1000;

        window.setTimeout(() => {
            this.setState({ received: false });
        }, TIMEOUT);
    };

    // 低频率轮询同步消息
    startMessageQueryingSlowly = () => {
        window.clearInterval(this.queryingInterval);
        window.clearInterval(this.rapidQueryingInterval);
        this.queryingInterval = window.setInterval(() => {
            if (this.isRouteAvaliable()) {
                this.queryNotification();
            }
        }, 20 * 1000);
        this.queryNotification();
    };

    // 高频率轮序同步消息
    startMessageQueryingRapidly = () => {
        window.sessionStorage.setItem('querying_notification', true);
        window.clearInterval(this.rapidQueryingInterval);
        window.clearInterval(this.queryingInterval);
        this.rapidQueryingInterval = window.setInterval(() => {
            if (this.isRouteAvaliable()) {
                this.queryNotification();
            }
        }, 6 * 1000);
        this.queryNotification();
    };

    // 查询是否有新消息提醒
    queryNotification = () => {
        // 如果不是要显示的路由，则不请求
        if (!this.isRouteAvaliable()) {
            return;
        }

        // 第一次请求查看消息提醒
        WPT.getData(API.realNews, { t: Date.now() }, ({ code, data }) => {
            if (code == 0 && data.msgType) {
                this.setState({
                    received: true,
                    messageUrl: data.redirectUrl,
                    pushType: data.msgType,
                    pushContent: data.msg,
                    pushUserinfo: data.msgUserinfo,
                    type: PUSH,
                });

                this.setAutoReset();
            }
        });
    };

    // 页面路由变化 hook
    pageChangeListener = () => {
        // $(document).off('Page:change').on('Page:change', (_event, { url }) => {
        //     this.setState({ currentRoute: url });
        //     // 检测到进入消息中心，开始高速轮询
        //     if (WPT.Util.urlParse(url).pathname === CALL_CENTER_ROUTE) {
        //         this.startMessageQueryingRapidly();
        //     }
        // });
        WPT.pageChange.append('messageAlert', (url) => {
            this.setState({ currentRoute: url });
            // 检测到进入消息中心，开始高速轮询
            if (WPT.Util.urlParse(url).pathname === CALL_CENTER_ROUTE) {
                this.startMessageQueryingRapidly();
            }
        });
    };

    redirectToMessage = () => {
        const { messageUrl } = this.state;

        this.setState({
            received: false,
        });
        // location.href = messageUrl;
        WPT.clearPage('/webApp/im/sellerChat');
        WPT.clearPage('/webApp/im/callCenter');
        WPT.clearPage('/webApp/im/buyerChat');
        WPT.showPage(messageUrl);
    };

    handleTouchStart = (event) => {
        const { clientX, clientY } = event.touches[0];

        this.touchStartX = clientX;
        this.touchStartY = clientY;
    };

    handleTouchMove = (event) => {
        const { clientX, clientY } = event.touches[0];

        this.touchEndX = clientX;
        this.touchEndY = clientY;
    };

    handleTouchEnd = () => {
        const { top, bottom, left, right } = this.container;

        if (this.touchEndY < top || this.touchEndY > bottom) {
            return;
        }

        const xDistance = this.touchEndX - this.touchStartX;
        // 滑动距离足够触发移除行为
        if (xDistance > 20) {
            this.API.dismiss();
            this.setState({ received: false });
        } else if (!this.touchEndX || (this.touchEndX >= left && this.touchEndX <= right)) {
            this.redirectToMessage();
        }
    };

    handlePushTouchStart = (event) => {
        event.preventDefault();

        const { clientX, clientY } = event.touches[0];

        this.pushTouchStartX = clientX;
        this.pushTouchStartY = clientY;
    };

    handlePushTouchMove = (event) => {
        const { clientX, clientY } = event.touches[0];

        this.pushTouchEndX = clientX;
        this.pushTouchEndY = clientY;
    };

    handlePushTouchEnd = () => () => {
        const { top, bottom, left, right } = this.pushContainer;

        if (this.pushTouchEndX < left || this.pushTouchEndX > right) {
            return;
        }

        const yDistance = this.pushTouchStartY - this.pushTouchEndY;
        // 滑动距离足够触发移除行为
        if (yDistance > 20) {
            this.setState({ received: false });
        } else if (!this.pushTouchEndY || (this.pushTouchEndY >= top && this.pushTouchEndY <= bottom)) {
            this.redirectToMessage();
        }
    };

    handlePushClick = () => {
        if ($.os.phone) {
            return;
        }

        this.redirectToMessage();
    };

    handleClick = () => {
        if ($.os.phone) {
            return;
        }

        this.redirectToMessage();
    };

    alertRef = (container) => {
        if (!container) {
            return;
        }

        const { top, bottom, left, right } = container.getBoundingClientRect();

        this.container = {
            top,
            bottom,
            left,
            right,
        };
    };

    pushRef = (container) => {
        if (!container) {
            return;
        }

        const { top, bottom, left, right } = container.getBoundingClientRect();

        this.pushContainer = {
            top,
            bottom,
            left,
            right,
        };
    };

    // 判断用户是否第一次进入微拍堂页面
    isFirstVisit = () => !document.referrer && !WPT.referrer;

    renderNotification = () => {
        const { count, received } = this.state;
        const countText = count > 9 ? '9+' : count;
        return (
            <CSSTransitionGroup
                transitionName={{
                    enter: styles.enter,
                    enterActive: styles.enterActive,
                    leave: styles.leave,
                    leaveActive: styles.leaveActive,
                }}
                transitionEnterTimeout={200}
                transitionLeaveTimeout={200}
                component="div"
            >
                {this.isRouteAvaliable() && this.isFirstVisit() && received && (
                    <div
                        ref={this.alertRef}
                        onTouchStart={this.handleTouchStart}
                        onTouchMove={this.handleTouchMove}
                        onTouchEnd={this.handleTouchEnd}
                        onClick={this.handleClick}
                        className={styles.container}
                    >
                        <i className={cx('wptFM icon-fm-message', styles.icon)} />
                        <div className={styles.notification}>{countText}</div>
                    </div>
                )}
            </CSSTransitionGroup>
        );
    };

    renderPush = () => {
        const { pushType, pushContent, pushUserinfo, received, type } = this.state;

        let icon = (
            <div className={styles.iconContainer}>
                <i className={cx('wptFM icon-fm-message', styles.pushIcon)} />
            </div>
        );

        let title = <span className={styles.title}>用户消息</span>;

        if (pushType === NOTIFICATION) {
            title = <span className={styles.title}>消息</span>;
        }
        if (pushType === 'system') {
            icon = (
                <div className={cx(styles.iconContainer, styles.system)}>
                    <i className={cx('wptFM icon-fm-logoicon', styles.pushIcon)} />
                </div>
            );

            title = <span className={styles.title}>系统消息</span>;
        }

        if (pushType === 'user' && pushUserinfo) {
            icon = (
                <div className={styles.iconContainer}>
                    <div className={cx(styles.userIcon)} style={{ backgroundImage: `url(${pushUserinfo.head})` }} />
                </div>
            );

            title = <span className={cx(styles.title, styles.name)}>{pushUserinfo.name}</span>;
        }

        return (
            <CSSTransitionGroup
                transitionName={{
                    enter: styles.pushEnter,
                    enterActive: styles.pushEnterActive,
                    leave: styles.pushLeave,
                    leaveActive: styles.pushLeaveActive,
                }}
                transitionEnterTimeout={200}
                transitionLeaveTimeout={200}
                component="div"
            >
                {this.isRouteAvaliable() && received && (
                    <div
                        ref={this.pushRef}
                        onTouchStart={this.handlePushTouchStart}
                        onTouchMove={this.handlePushTouchMove}
                        onTouchEnd={this.handlePushTouchEnd(type)}
                        onClick={this.handlePushClick}
                        className={styles.pushContainer}
                    >
                        <div className={styles.head}>
                            {icon}
                            {title}
                            <span className={styles.time}>现在</span>
                        </div>
                        <div className={styles.content}>{pushContent}</div>
                    </div>
                )}
            </CSSTransitionGroup>
        );
    };

    render() {
        // const { type } = this.state;

        // if (type === NOTIFICATION) {
        //     return this.renderNotification();
        // }

        return this.renderPush();
    }
}

// 挂载消息提醒组件
ReactDOM.render(<MessageAlert />, document.getElementById('message-alert'));
